﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using Microsoft.VisualBasic;
namespace Convert.DataAccess
{
    public class Encryption
    {
        public const String strPrivateBaseKey = "rG5{w2l?LpB8v1-$@m93&80!@4+]Zd^)";
        public static String strStoreBaseKey=null;
        public static string EncryptData(string strData, Boolean blnSystemMasterKey = true, String strSaltedKey = null)
        {
            if (blnSystemMasterKey)
                return EncryptString128Bit(strData, strPrivateBaseKey);
            else
            {
                if (strSaltedKey == null)
                    return EncryptString128Bit(strData, strStoreBaseKey);
                else
                    return EncryptString128Bit(strData, strSaltedKey);
            }
        }

        public static string DecryptData(string strData, Boolean blnSystemMasterKey = true, String strSaltedKey = null)
        {
            if (blnSystemMasterKey)
                return DecryptString128Bit(strData, strPrivateBaseKey);
            else
            {
                if (strSaltedKey == null)
                    return DecryptString128Bit(strData, strStoreBaseKey);
                else
                    return DecryptString128Bit(strData, strSaltedKey);
            }
        }
        /*
        public string CreateStoreEncryptionKey()
        {
        int intHashValue = (int) Conversion.Int((32767 * VBMath.Rnd()) + 1);
        RandomKeyGenerator KeyGen = new RandomKeyGenerator();
        KeyGen.KeyLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+{}|:<>?~[]\;',./";
        KeyGen.KeyNumbers = "0123456789";
        KeyGen.KeyChars = 32;
        return KeyGen.Generate(intHashValue);
        }
        */
        public static string GetClerkSaltedEncryptKey(string strClerkCode)
        {
            return (strPrivateBaseKey.Substring(0, 4) +
                    strPrivateBaseKey.Substring(8, 9) +
                    strPrivateBaseKey.Substring(7, 11) +
                    strClerkCode +
                    strPrivateBaseKey.Substring(20, 6)).Trim();
        }

        public static String EncryptString128Bit(String vstrTextToBeEncrypted, String vstrEncryptionKey){
        Byte[] bytValue;
        Byte[] bytKey;
        Byte[] bytEncoded = {0};
        Byte[] bytIV = {121, 241, 10, 1, 132, 74, 11, 39, 255, 91, 45, 78, 14, 211, 22, 62};
        int intLength;
        int intRemaining;
        MemoryStream objMemoryStream = new MemoryStream();
        CryptoStream objCryptoStream;
        RijndaelManaged objRijndaelManaged;
        vstrTextToBeEncrypted = StripNullCharacters(vstrTextToBeEncrypted);

        bytValue = Encoding.ASCII.GetBytes(vstrTextToBeEncrypted.ToCharArray());

        intLength = vstrEncryptionKey.Length;

        if(intLength >= 32)
        {
            vstrEncryptionKey = Strings.Left(vstrEncryptionKey, 32);
        }
        else
        {
            intLength = vstrEncryptionKey.Length;
            intRemaining = 32 - intLength;
            vstrEncryptionKey = vstrEncryptionKey + Strings.StrDup(intRemaining, "X");
        }
        bytKey = Encoding.ASCII.GetBytes(vstrEncryptionKey.ToCharArray());

        objRijndaelManaged = new RijndaelManaged();

            objCryptoStream = new CryptoStream(objMemoryStream, objRijndaelManaged.CreateEncryptor(bytKey, bytIV), CryptoStreamMode.Write);
            objCryptoStream.Write(bytValue, 0, bytValue.Length);
            objCryptoStream.FlushFinalBlock();
            bytEncoded = objMemoryStream.ToArray();
            objMemoryStream.Close();
            objCryptoStream.Close();
        return System.Convert.ToBase64String(bytEncoded);
        }

        public static string DecryptString128Bit(string vstrStringToBeDecrypted, string vstrDecryptionKey)
        {
            Byte[] bytDataToBeDecrypted;
            Byte[] bytIV = { 121, 241, 10, 1, 132, 74, 11, 39, 255, 91, 45, 78, 14, 211, 22, 62 };
            RijndaelManaged objRijndaelManaged = new RijndaelManaged();
            MemoryStream objMemoryStream;
            CryptoStream objCryptoStream;
            Byte[] bytDecryptionKey;
            int intLength;
            int intRemaining;
            string strReturnString = String.Empty;
            bytDataToBeDecrypted = System.Convert.FromBase64String(vstrStringToBeDecrypted);
            intLength = vstrDecryptionKey.Length;
            if (intLength >= 32)
                vstrDecryptionKey = Strings.Left(vstrDecryptionKey, 32);
            else
            {
                intLength = vstrDecryptionKey.Length;
                intRemaining = 32 - intLength;
                vstrDecryptionKey = vstrDecryptionKey + Strings.StrDup(intRemaining, "X");
            }

            bytDecryptionKey = Encoding.ASCII.GetBytes(vstrDecryptionKey.ToCharArray());
            Byte[] bytTemps = new Byte[bytDataToBeDecrypted.Length];
            objMemoryStream = new MemoryStream(bytDataToBeDecrypted);
            objCryptoStream = new CryptoStream(objMemoryStream, objRijndaelManaged.CreateDecryptor(bytDecryptionKey, bytIV), CryptoStreamMode.Read);
            objCryptoStream.Read(bytTemps, 0, bytTemps.Length);
            objCryptoStream.FlushFinalBlock();
            objMemoryStream.Close();
            objCryptoStream.Close();
            return StripNullCharacters(Encoding.ASCII.GetString(bytTemps));
        }

        public static string StripNullCharacters(string vstrStringWithNulls)
        {
            int intPosition;
            string strStringWithOutNulls;
            intPosition = 1;
            strStringWithOutNulls = vstrStringWithNulls;
            while (intPosition > 0)
            {
                intPosition = Strings.InStr(intPosition, vstrStringWithNulls, Constants.vbNullChar);

                if (intPosition > 0)
                {
                    strStringWithOutNulls = Strings.Left(strStringWithOutNulls, intPosition - 1) + Strings.Right(strStringWithOutNulls, (strStringWithOutNulls.Length) - intPosition);
                }

                if (intPosition > strStringWithOutNulls.Length)
                {
                    break;
                }
            }
            return strStringWithOutNulls;
        }
    }
}
